package com.hulk.dryad.activiti7.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hulk.dryad.activiti7.api.vo.DefinitionIdVO;
import com.hulk.dryad.activiti7.api.vo.ProcessDefinitionVO;
import com.hulk.dryad.activiti7.mapstruct.DefinitionIdStruct;
import com.hulk.dryad.activiti7.mapstruct.ProcessDefinitiontStruct;
import com.hulk.dryad.common.annotation.OperLog;
import com.hulk.dryad.common.annotation.PrintlnLog;
import com.hulk.dryad.common.annotation.Idempotent;
import com.hulk.dryad.common.component.R;
import com.hulk.dryad.common.constant.enums.ActionType;
import com.hulk.dryad.persistence.entity.DefinitionId;
import com.hulk.dryad.persistence.entity.ProcessDefinitionModel;
import com.hulk.dryad.activiti7.service.IProcessDefinitionService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


/**
 *  流程定义处理
 *
 * @author hulk
 * @date 2019-10-18 17:18:42
 */
@Api(value = "processDefinition", tags = "流程定义模块")
@AllArgsConstructor
@RestController
@RequestMapping("/workflow/processDefinition")
public class ProcessDefinitionController  {

    private IProcessDefinitionService processDefinitionService;


    /**
     * 获取流程定义集合
     *
	 * @param page
     * @param processDefinitionVO
     * @return R
     */
	@ApiOperation(value = "getDefinitionPage", notes = "获取流程定义分页信息")
	@PrintlnLog
    @GetMapping(value = "/page")
    public R<Page> getDefinitionPage(Page page , ProcessDefinitionVO processDefinitionVO) {
		ProcessDefinitionModel processDefinitionModel = new ProcessDefinitionModel();
		BeanUtils.copyProperties(processDefinitionVO, processDefinitionModel);
		Page<ProcessDefinitionModel> rpm =processDefinitionService.getProcessDefinitionPage(page,processDefinitionModel);
		Page<ProcessDefinitionVO> rpv =	ProcessDefinitiontStruct.INSTANCE.from(rpm);
		return R.ok(rpv);

    }

    /**
     * @param instanceId
     * @return
     */
	@ApiOperation(value = "getDefinitionsByInstanceId", notes = "通过实例ID获取流程定义信息")
	@PrintlnLog
    @GetMapping(value = "/getDefinition/{instanceId}")
    public R getDefinitionsByInstanceId(@PathVariable("instanceId") String instanceId){
		DefinitionId definitionId =processDefinitionService.getDefinitionByInstanceId(instanceId);
		DefinitionIdVO vo =	DefinitionIdStruct.INSTANCE.from(definitionId);
        return R.ok(vo);
    }

    /**
     * 删除流程定义
     *
     * @param deploymentId
     * @return
     */
	@ApiOperation(value = "removeDefinition", notes = "删除流程定义")
	@OperLog(value ="删除流程定义",action = ActionType.DEL)
	@Idempotent
    @DeleteMapping(value = "/remove/{deploymentId}")
    public R removeDefinition(@PathVariable("deploymentId") String deploymentId) {
	    processDefinitionService.removeProcessDefinitionById(deploymentId);
        return R.ok();
    }

    /**
     * 启动挂起流程流程定义
     *
     * @param processDefinitionVO
     * @return
     */
	@ApiOperation(value = "suspendOrActiveApply", notes = "启动挂起流程流程定义")
	@OperLog(value ="启动挂起流程流程定义",action = ActionType.OTHER)
	@Idempotent
    @PostMapping("/suspendOrActiveApply")
    public R suspendOrActiveApply(@RequestBody ProcessDefinitionVO processDefinitionVO) {
		ProcessDefinitionModel processDefinitionModel = new ProcessDefinitionModel();
		BeanUtils.copyProperties(processDefinitionVO, processDefinitionModel);
        processDefinitionService.suspendOrActiveApply(processDefinitionModel.getId(), processDefinitionModel.getSuspendState());
		return R.ok();
    }

	/**
	 * 上传并部署流程定义
	 *
	 * @param file
	 * @return
	 * @throws IOException
	 */
	@ApiOperation(value = "uploadStreamAndDeployment", notes = "上传并部署流程定义")
	@OperLog(value ="上传并部署流程定义",action = ActionType.OTHER)
	@Idempotent
	@PostMapping(value = "/uploadStreamAndDeployment")
	public R uploadStreamAndDeployment(@RequestPart("file") MultipartFile file, @RequestParam("deploymentName")String deploymentName) throws IOException {

		if (!file.isEmpty()) {
			processDefinitionService.uploadStreamAndDeployment(file, deploymentName);
			return R.ok();
		}
		return R.failed("不允许上传空文件！");
	}
    /**
     * 上传流程流程定义
     *
     * @param multipartFile
     * @return R
     * @throws IOException
     */
	@ApiOperation(value = "upload", notes = "上传流程流程定义")
	@OperLog(value ="上传流程流程定义",action = ActionType.OTHER)
	@Idempotent
    @PostMapping(value = "/upload")
    public R upload( @RequestPart("processFile") MultipartFile multipartFile) throws IOException {

        if (!multipartFile.isEmpty()) {
            String fileName = processDefinitionService.upload(multipartFile);
            return R.ok("操作成功", fileName);
        }
        return R.failed("不允许上传空文件！");
    }


    /**
     * 通过stringBPMN添加流程定义
     *
     * @param stringBPMN
     * @return R
     */
	@ApiOperation(value = "addDeploymentByString", notes = "通过stringBPMN添加流程定义")
	@OperLog(value ="通过stringBPMN添加流程定义",action = ActionType.OTHER)
	@Idempotent
    @PostMapping(value = "/addDeploymentByString")
    public R addDeploymentByString(@RequestParam("stringBPMN") String stringBPMN,@RequestParam("deploymentName")String deploymentName) {
        processDefinitionService.addDeploymentByString(stringBPMN,deploymentName);
        return R.ok();

    }


    /**
     * 获取流程定义XML
     *
     * @param response
     * @param deploymentId
     * @param resourceName
     */
	@ApiOperation(value = "getDefinitionXML", notes = "获取流程定义XML")
    @GetMapping(value = "/getDefinitionXML")
    public void getProcessDefineXML(HttpServletResponse response,
                                    @RequestParam("deploymentId") String deploymentId,
                                    @RequestParam("resourceName") String resourceName) throws IOException {

        processDefinitionService.getProcessDefineXML(response, deploymentId, resourceName);
    }


}
